package com.itlong.cloud.utils.words;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.app.AppElevatorAuthDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardQRCodeElevatorAuthDTO;
import com.itlong.cloud.POJO.VO.app.AppElevatorAuthVO;
import com.itlong.cloud.POJO.VO.app.AppElevatorInfoVO;
import com.itlong.cloud.POJO.VO.app.AppEntranceOrCloudIntercomAuthVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.AppQrcodeProtocolVersionEnum;
import com.itlong.cloud.enumerate.AppQrcodeUserTypeEnum;
import com.itlong.cloud.enumerate.LanguageTypeEnum;
import com.itlong.cloud.enumerate.PropertyEquipTypeEnum;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.ErrorCode;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import org.apache.commons.lang.StringUtils;
import sun.misc.BASE64Decoder;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.NoSuchProviderException;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <desc>
 * 字符串数据操作帮助类
 * </desc>
 *
 * @craeteDate 2017/09/15
 */
public class StringHandlerUtil {
    public static final String REGEX_MOBILE = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$";


    /**
     * <desc>
     *      校验是否是手机号
     * </desc>
     *
     * @param phone
     * @return
     * @author Jiaqi.X
     * @createDate 2019/11/19
     */
    public static boolean checkIsPhone(String phone){
        return phone.matches(REGEX_MOBILE);
    }


    /**
     * <desc>
     *      去除字符串中的换行等字符
     * </desc>
     *
     * @param str
     * @return
     * @author Jiaqi.X
     * @createDate 2018/04/04
     */
    public static String replaceBlank(String str) {
        String dest = "";
        if (str!=null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    /**
     * <desc>
     *      用指定字符格式化字符串
     * <desc/>
     *
     * @param old 原字符串
     * @param  sub 指定字符串
     * @param len 格式化后字符串总长度
     * @param isAddAfter 为true则在后面添加，否则添加到前面
     * @param isCutMore 是否截断超出指定长度部分的字符串
     * @return
     * @author Chunjian.G
     * @createDate 2017-11-06
     */
    public static String formatStrLen(String old,
                                        String sub,
                                        int len,
                                        boolean isAddAfter,
                                        boolean isCutMore){
        StringBuilder sb = new StringBuilder();
        if (null == old){
            old = "";
        }
        if (null == sub){
            sub = "0";
        }
        int addLen = len - old.length();
        for (int i = 0; i < addLen; i++){
            sb.append(sub);
        }
        if (isAddAfter){
            sb.insert(0, old);
        }else {
            sb.append(old);
        }
        if (isCutMore){
            return sb.toString().substring(0, len);
        }else {
            return sb.toString();
        }
    }


    /**
     * <desc>
     *      将String字符串转为十六进制
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2017/12/19
     */
    public static String getQrcodeStringHex(String str){
        StringBuilder result=new StringBuilder();
        if(str.length() % 2==0) {
            for (int i = 0; i < str.length(); i+=2) {
                System.out.println(str.substring(i, i + 2));
                result.append(autlSupply(2,Integer.toHexString(Integer.valueOf(str.substring(i, i + 2))),"0"));
            }
        }
        return result.toString().toUpperCase();
    }


    /**
     * <desc>
     *      删除字符串开头和结尾中出现的特定字符
     * <desc/>
     *
     * @param source 源字符串
     * @param trimStr 要删除的字符
     * @return
     * @author Chunjian.G
     * @createDate 2017-11-10
     */
    public static String trim(String source, String trimStr){
        if (null == source){
            return null;
        }
        if (null == trimStr){
            return source;
        }
        if (source.length() < trimStr.length()){
            return source;
        }
        //从开始处 trim
        while (source.startsWith(trimStr)){
            source = copySubStr(source, trimStr.length(), source.length()-trimStr.length());
        }
        //从结尾处 trim
        while (source.endsWith(trimStr)){
            source = copySubStr(source, 0, source.length() - trimStr.length());
        }
        return source;
    }

    /**
     * <desc>
     *      获取空字符串或str
     * </desc>
     *
     * @param obj
     * @return
     * @author Jiaqi.X
     * @createDate 2017/12/25
     */
    public static String getEmptyOrStr(Object obj){
        if(obj==null){
            return "";
        }else{
            return obj.toString();
        }
    }

    /**
     * <desc>
     * 判断字符串是否为null或为空，并返回
     * </desc>
     *
     * @param str
     * @return
     * @author Jiaqi.X
     * @createDate 2017/09/15
     */
    public static String getStringOrNull(String str) {
        if (str != null) {
            if (str.equals("")) {
                return null;
            } else {
                return str;
            }
        }
        return null;
    }


    /**
     * <desc>
     * 自动填充字符串
     * </desc>
     *
     * @param length 长度
     * @param str    字符串
     * @param supply 待填充的字符
     * @return
     * @author Jiaqi.X
     * @createDate 2017/09/27
     */
    public static String autlSupply(int length, String str, String supply) {
        StringBuffer sb = new StringBuffer(str);
        while (sb.length() < length) {
            sb.insert(0, supply);
        }
        return sb.toString();
    }

    /**
     * <desc>
     *      末尾自动填充字符串
     * </desc>
     *
     * @param length 长度
     * @param str    字符串
     * @param supply 待填充的字符
     * @return
     * @author Jiaqi.X
     * @createDate 2017/09/27
     */
    public static String autlSupplyLast(int length, String str, String supply) {
        if(StringUtils.isBlank(str)){
            str="";
        }
        StringBuffer sb = new StringBuffer(str);
        while (sb.length() < length) {
            sb.append(supply);
        }
        return sb.toString();
    }

    /**
     * <desc>
     * 将,号分隔的字符串转换为数组
     * </desc>
     *
     * @param str
     * @return
     * @author Jiaqi.X
     * @createDate 2017/09/21
     */
    public static String[] splitString(String str) {
        int strLen;
        if (str != null && (strLen = str.length()) != 0) {
            if (!str.substring(0, strLen - 1).equals(",")) {
                return str.split(",");
            } else {
                return str.substring(0, strLen - 2).split(",");
            }
        } else {
            return new String[]{};
        }
    }

    /**
     * <desc>
     * 将,号分隔的字符串转换为数组
     * </desc>
     *
     * @param str
     * @return
     * @author Jiaqi.X
     * @createDate 2017/09/21
     */
    public static List<String> splitStringToArray(String str) {
        int strLen;
        if (str != null && (strLen = str.length()) != 0) {
            if (!str.substring(0, strLen - 1).equals(",")) {
                return new ArrayList<>(Arrays.asList(str.split(",")));
            } else {
                return new ArrayList<>(Arrays.asList(str.substring(0, strLen - 2).split(",")));
            }
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * <desc>
     * 将自定义符号号分隔的字符串转换为数组
     * </desc>
     *
     * @param str
     * @return
     * @author Jiaqi.X
     * @createDate 2017/09/21
     */
    public static String[] splitString(String str,String custom) {
        int strLen;
        if (str != null && (strLen = str.length()) != 0) {
            if (!str.substring(0, strLen - 1).equals(custom)) {
                return str.split(custom);
            } else {
                return str.substring(0, strLen - 2).split(custom);
            }
        } else {
            return new String[]{};
        }
    }

    /**
     * <desc>
     *      将,号分隔的字符串转换为List
     * <desc/>
     *
     * @param str
     * @return
     * @author Chunjian.G
     * @createDate 2017-12-15
     */
    public static List<String> splitStringList(String str){
        String[] arr = splitString(str);
        List<String> list = new ArrayList<>();
        for (String value: arr){
            list.add(value);
        }
        return list;
    }

    public static boolean isEmail(String emailContent) {
        Pattern pattern = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");

        Matcher matcher = pattern.matcher(emailContent);
        return matcher.matches();
    }


    /**
     * <desc>
     * 获取字字符串，避免索引越界异常.
     * </desc>
     *
     * @param sourceStr  源字符串
     * @param startIndex 开始索引
     * @param copyLen    拷贝长度
     * @return 子字符串
     * @author LewisLouis
     * @createDate 2017-10-11
     */
    public static String copySubStr(String sourceStr, int startIndex, int copyLen) {
        if (startIndex < 0){
            startIndex = 0;
        }
        if (sourceStr.length() < startIndex + 1) // 若索引直接越界则返回空字符串
        {
            return "";
        }
        if (copyLen > sourceStr.length() - startIndex) // 若需复制到的的字符串索引已越界则返回所有能够提供的字符串即可
        {
            return sourceStr.substring(startIndex, sourceStr.length());
        }
        return sourceStr.substring(startIndex, startIndex + copyLen);
    }

    /**
     * <desc>
     * 将字符串转换为整型.
     * </desc>
     *
     * @param str      待转换的字符串
     * @param defValue 转换失败后使用的默认结果
     * @return 转换的整型结果
     * @author LewisLouis
     * @createDate 2017-10-12
     */
    public static int strToIntDef(String str, int defValue) {
        return strToIntDef(str, defValue, 10);
    }

    /**
     * <desc>
     * 将字符串转换为整型.
     * </desc>
     *
     * @param str      待转换的字符串
     * @param defValue 转换失败后使用的默认结果
     * @param fromBase 字符串表示的进制 如“A0C”，代表16进制字符串
     * @return 转换的整型结果
     * @author LewisLouis
     * @createDate 2017-10-12
     */
    public static int strToIntDef(String str, int defValue, int fromBase) {
        int intRes;
        try {
            if (null == str || str.trim().equals("")){
                return defValue;
            }
            intRes = Integer.parseInt(str, fromBase);
        } catch (Exception e) {
            intRes = defValue;
        }
        return intRes;
    }

    /**
     * <desc>
     *      将字符串转换为Long(十进制)
     * <desc/>
     *
     * @param str      待转换的字符串
     * @param defValue 转换失败后使用的默认结果
     * @return 转换的长整型结果
     * @author Chunjian.G
     * @createDate 2017-12-14
     */
    public static long strToLongDef(String str, long defValue){
        return strToLongDef(str, defValue, 10);
    }

    /**
     * <desc>
     *      将字符串转换为Long
     * <desc/>
     *
     * @param str      待转换的字符串
     * @param defValue 转换失败后使用的默认结果
     * @param fromBase 字符串表示的进制 如“A0C”，代表16进制字符串
     * @return 转换的长整型结果
     * @author Chunjian.G
     * @createDate 2017-12-14
     */
    public static long strToLongDef(String str, long defValue, int fromBase){
        long longRes;
        try {
            if (null == str || str.trim().equals("")){
                return defValue;
            }
            longRes = Long.parseLong(str, fromBase);
        }catch (Exception e){
            longRes = defValue;
        }
        return longRes;
    }

    /**
     * <desc>
     *      进制转换
     * <desc/>
     *
     * @param str 需转换的字符串
     * @return
     * @author zhangs
     * @createDate 2017/10/10
     */
    public static String binaryToHex(String str)
    {
        if ((StringUtils.isBlank(str)) || (str.length() % 8 != 0)) {
            return null;
        }
        StringBuffer tmp = new StringBuffer();
        int iTmp = 0;
        for (int i = 0; i < str.length(); i += 4) {
            iTmp = 0;
            for (int j = 0; j < 4; j++) {
                iTmp += Integer.parseInt(str.substring(i + j, i + j + 1)) << (4 - j - 1);
            }
            tmp.append(Integer.toHexString(iTmp));
        }
        return tmp.toString();
    }

    /**
     * <desc>
     *      进制转换
     * <desc/>
     *
     * @param hexString 需转换的字符串
     * @return
     * @author zhangs
     * @createDate 2017/10/10
     */
    public static String hexToBinary(String hexString)
    {
        if ((StringUtils.isBlank(hexString)) || hexString.length() % 2 != 0 || hexString.indexOf("null")>=0 ) {
            return "";
        }
        StringBuffer tmp = new StringBuffer();
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < hexString.length(); i++) {
            tmp.append("0000").append(Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i+1), 16)));
            stringBuffer.append(tmp.toString().substring(tmp.length() - 4));
        }
        return stringBuffer.toString();
    }

    /**
     * <desc>
     *      通过楼层标识生成电梯权限
     * <desc/>
     *
     * @param floorSigns 楼层标识1,3,5=》10101000=》A8
     * @return
     * @author zhangs
     * @createDate 2017/10/10
     */
    public static String getAuthCodeBynNturalFloors(String floorSigns) {
        String[] binaryStr = new String[PlatformConstants.MAX_ELEVATOR_FLOORNUM + 1];
        for(int i=0;i<binaryStr.length;i++) {
            binaryStr[i] = "0";
        }
        if(floorSigns != null&&!"".equals(floorSigns)) {
            String[] temp = floorSigns.split(",");
            for(int i=0;i<temp.length;i++) {
                String str = temp[i];
                if(str!=null&&!"".equals(str)&&!"null".equals(str)) {
                    int a = Integer.parseInt(str);
                    if(a > 0 && a <= PlatformConstants.MAX_ELEVATOR_FLOORNUM) {
                        binaryStr[a-1] = "1";
                    }
                }
            }
        }
        StringBuilder sBuilder = new StringBuilder();
        for(int i=0;i<binaryStr.length;i++) {
            sBuilder.append(binaryStr[i].toString());
        }
        return binaryToHex(copySubStr(sBuilder.toString(), 0, PlatformConstants.MAX_ELEVATOR_FLOORNUM)).toUpperCase();
    }

    /**
     * <desc>
     *      通过28位楼层权限获取对应的楼层标识字符串(以,拼接)
     * <desc/>
     *
     * @param authCode 楼层权限
     * @return
     * @author zhangs
     * @createDate 2017/10/10
     */
    public static String getNaturalFloorsByAuthCode(String authCode) {
        if (StringUtils.isBlank(authCode)){
            return "";
        }
        int hexFloorLength = PlatformConstants.MAX_ELEVATOR_FLOORNUM / 4;
        if (authCode.length() < hexFloorLength){
            authCode = StringHandlerUtil.autlSupplyLast(hexFloorLength,authCode,"0");
        }
        String binaryAuthCode = hexToBinary(authCode);
        String[] binaryStr = new String[PlatformConstants.MAX_ELEVATOR_FLOORNUM + 1];
        if(StringUtils.isBlank(binaryAuthCode)) {
            return "";
        }
        for(int i=0;i+1<binaryStr.length;i++) {
            binaryStr[i] = binaryAuthCode.substring(i, i+1);
        }
        StringBuffer naturalFloorSb = new StringBuffer();
        for(int i=0;i<binaryStr.length;i++) {
            if("1".equals(binaryStr[i])) {
                naturalFloorSb.append(i+1);
                naturalFloorSb.append(",");
            }
        }
        String naturalFloors = naturalFloorSb.toString();
        if(naturalFloors.endsWith(",")){
            naturalFloors = naturalFloors.substring(0, naturalFloors.length()-1);
        }
        return naturalFloors;
    }

    /**
     * <desc>
     *      去除字符串结尾的用于拼接的逗号
     * <desc/>
     *
     * @param stringBuffer 需要操作的字符串
     * @return StringBuffer
     * @author zhangs
     * @createDate 2017/10/10
     */
    public static StringBuffer clearComma(StringBuffer stringBuffer) {
        if((stringBuffer == null) || (stringBuffer.length() == 0)) {
            return new StringBuffer();
        }
        if(stringBuffer.toString().endsWith(",")) {
            stringBuffer.deleteCharAt(stringBuffer.length() - 1);
        }
        return stringBuffer;
    }

    /**
    * <desc>
    *    比较字符串是否相等，若任意一个比较字符串存在NULL\Empty，一律视为不相等.
    * </desc>
    *
    * @param A 字符串A
    * @param B 字符串B
    * @return True 相等  false不相等
    * @author LewisLouis
    * @createDate 2017-10-20
    */
    public static boolean compareStrWithOutEmpty(String A, String B){

        if ((StringUtils.isEmpty(A)) || (StringUtils.isEmpty(B)))
        {
            return  false;
        }
        return A.equals(B);
    }

    /**
     * <desc>
     *    比较字符串是否相等，若任意一个比较字符串存在NULL\Empty，一律视为不相等.
     * </desc>
     *
     * @param A 字符串A
     * @param B 字符串B
     * @return True 相等  false不相等
     * @author LewisLouis
     * @createDate 2017-10-20
     */
    public static boolean compareStrIgnoreCaseWithOutEmpty(String A, String B){

        if ((StringUtils.isEmpty(A)) || (StringUtils.isEmpty(B)))
        {
            return  false;
        }
        return A.equalsIgnoreCase(B);
    }
    /**
     * <desc>
     *      传入object 返回null或obj.toString
     * </desc>
     *
     * @param obj
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/24
     */
    public static String getNullOrStringForObject(Object obj){
        if(obj!=null){
            return obj.toString();
        }
        return null;
    }

    /**
     * <desc>
     *      传入object 返回null或obj.toString
     * </desc>
     *
     * @param obj
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/24
     */
    public static String getEmptyOrStringForObject(Object obj){
        if(obj!=null){
            return obj.toString();
        }
        return "";
    }

    /**
     * <desc>
     *      通过自然数或者二进制数查找某一字符的所有下标(机号)，使用，号分隔
     * </desc>
     *
     * @param auth
     * @param vaild
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/02
     */
    public static String convertAuth(String auth,String vaild){
        int index=0;      //用来记录二进制机号下标
        StringBuilder convertAuth = new StringBuilder(); //转换后的字符串 ，号分隔
        if (auth != null && !auth.isEmpty()) {
            while (index >= 0) {
                index = auth.indexOf(vaild, index);
                if (index >= 0) {
                    convertAuth.append(autlSupply(4, String.valueOf(++index), "0") + ",");
                }
            }
        }else{
            return null;
        }
        if(convertAuth.length()==0){
            return "";
        }else {
            return convertAuth.toString().substring(0, convertAuth.length() - 1);
        }
    }

    /**
     * <desc>
     *      通过自然数或者二进制数查找某一字符的楼层
     * </desc>
     *
     * @param auth
     * @param vaild
     * @return号
     * @author Jiaqi.X
     * @createDate 2017/11/02
     */
    public static String convertFloor(String auth,String vaild){
        int index=0;      //用来记录二进制机号下标
        StringBuilder convertAuth = new StringBuilder(); //转换后的字符串 ，号分隔
        if (auth != null && !auth.isEmpty()) {
            while (index >= 0) {
                index = auth.indexOf(vaild, index);
                if (index >= 0) {
                    convertAuth.append(String.valueOf(++index) + ",");
                }
            }
        }else{
            return "";
        }
        if(StringUtils.isNotBlank(convertAuth.toString())) {
            return convertAuth.toString().substring(0, convertAuth.length() - 1);
        }else{
            return "";
        }
    }


    /**
     * <desc>
     *      解析门禁和云对讲的机号
     *      规则12785837478   代表有 1 2 4 5 6 7 9 11号机权限 7代表无权限
     * </desc>
     *
     * @param auth 云对讲机号权限码
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/17
     */
    public static String convertIntercomAndEntranceDeviceId(String auth){
        int index=1;      //用来记录二进制机号下标
        StringBuilder convertAuth = new StringBuilder(); //转换后的字符串 ，号分隔
        if (auth != null && !auth.isEmpty()) {
            while (index <= auth.length()) {
                String now=auth.substring(0,index);
                if (!now.substring(now.length()-1,now.length()).equals("7")) {
                    convertAuth.append(autlSupply(4,index+"","0") + ",");
                }
                index++;
            }
        }else{
            return null;
        }
        return convertAuth.toString();
    }


    /**
     * <desc>
     *      获取设备唯一码（项目id + 设备类型 + 设备机号）
     * <desc/>
     *
     * @param projectId 项目编号
     * @param devType 设备类型：1电梯，2门禁，3云对讲
     * @param devId 机号
     * @return
     * @author Chunjian.G
     * @createDate 2017-11-06
     */
    public static String getDeviceUniqueId(String projectId, Integer devType, String devId){
        String uniqueId = projectId + devType +
                formatStrLen(devId.trim(), "0", 4, false, true);
        return uniqueId;
    }

    /**
     * <desc>
     *      根据设备唯一码获取设备机号
     * <desc/>
     *
     * @param deviceUnique 设备唯一码
     * @return 4位设备机号
     * @author Chunjian.G
     * @createDate 2017-11-06
     */
    public static String getDeviceIdByDeviceUnique(String deviceUnique){
        if (null == deviceUnique || !deviceUnique.trim().matches("[0-9]{13}")){
            return null;
        }else {
            return copySubStr(deviceUnique, 9, 4);
        }
    }
    /**
     * <desc>
     *      根据设备唯一码获取设备所属项目id
     * <desc/>
     *
     * @param deviceUnique 设备唯一码
     * @return
     * @author Chunjian.G
     * @createDate 2017-11-08
     */
    public static String getProjectIdByDeviceUnique(String deviceUnique){
        if (null == deviceUnique || !deviceUnique.trim().matches("[0-9]{13}")){
            return null;
        }else {
            return copySubStr(deviceUnique, 0, 8);
        }
    }
    /**
     * <desc>
     *      根据设备唯一码获取设备类型
     * <desc/>
     *
     * @param deviceUnique 设备唯一码
     * @return
     * @author Chunjian.G
     * @createDate 2017-11-08
     */
    public static Integer getDeviceTypeByDeviceUnique(String deviceUnique){
        if (null == deviceUnique || !deviceUnique.trim().matches("[0-9]{13}")){
            return null;
        }else {
            return strToIntDef(copySubStr(deviceUnique,8,1), 0);
        }
    }


    /**
     * <desc>
     *      组装二维码设备机号
     *      每个机号1-2Byte，首字节最高位为0，表示机号只占一个字节，范围0x00-0x7F，
     *      即0-127号机；首字节最高位为1，表示机号占2Byte,0x8000-0x8300，即128-384号机。
     *      例子中3部梯的机号为“02 7F 81 00”，
     *      02表示2号机、7F表示127号机；8100表示128号机 == 1*128
     * </desc>
     *
     * @param deviceIds 机号数组
     * @return
     * @author Jiaqi.X
     * @cerateDate 2017/11/15
     */
    public static String assembleDeviceNum(String[] deviceIds){
        StringBuilder qrcode=new StringBuilder();
        for(int i=0;i<deviceIds.length;i++){
            int deviceId=Integer.valueOf(deviceIds[i]);
            if(deviceId<=127){
                qrcode.append(autlSupply(2,Integer.toHexString(deviceId).toUpperCase(),"0"));
            }else{
                qrcode.append(autlSupply(2,Integer.toHexString(128+deviceId/128).toUpperCase(),"0"));
                qrcode.append(autlSupply(2,Integer.toHexString(deviceId-128*(deviceId/128)).toUpperCase(),"0"));
            }
        }
        return qrcode.toString();
    }


    public static String assembleQrcodeDeviceNum(String[] deviceIds){
        deviceIds = sortStringArray(deviceIds);
        StringBuilder qrcode = new StringBuilder();
        for(int i=0 ; i<deviceIds.length;i++){
            int deviceId=Integer.valueOf(deviceIds[i]);
            if(i == 0){
                qrcode.append(Integer.toHexString(deviceId));
                continue;
            }
            int upDeviceId = Integer.valueOf(deviceIds[i-1]);
            if(upDeviceId+1 == deviceId){
                if( !qrcode.substring(qrcode.length()-1,qrcode.length()).equals("-")) {
                    qrcode.append("-");
                }
                if(i == deviceIds.length -1 ){
                    qrcode.append(Integer.toHexString(deviceId));
                }
                continue;
            }
            if(upDeviceId+1 != deviceId){
                if(qrcode.substring(qrcode.length()-1,qrcode.length()).equals("|") || qrcode.substring(qrcode.length()-1,qrcode.length()).equals("-")) {
                    qrcode.append(Integer.toHexString(upDeviceId));
                }
                qrcode.append("|");
                qrcode.append(Integer.toHexString(deviceId));
            }
        }
        return qrcode.toString().toUpperCase();
    }


    /**
     * <desc>
     *      获取组装后的机号或楼层数据
     * </desc>
     *
     * @param content
     * @return
     * @author Jiaqi.X
     * @createDate 2019/10/16
     */
    public static String assembleNewDeviceNum(String[] content){
        try {
            List<Integer> list = new ArrayList<>();
            Integer max = null;
            for (String con : content) {
                Integer c = Integer.valueOf(con);
                list.add(c);
                if (max == null) {
                    max = c;
                } else if (c > max) {
                    max = c;
                }
            }
            StringBuilder result = new StringBuilder();
            for (int i = 1; i <= max; i++) {
                Integer n = i;
                if (list.stream().filter(num -> num.equals(n)).findFirst().isPresent()) {
                    result.append("1");
                } else {
                    result.append("0");
                }
            }
            String res = result.toString();
            while (StringUtils.isBlank(res) || (res.length() % 8 != 0)) {
                res += "0";
            }
            return binaryToHex(res).toUpperCase();
        }catch (Exception e){
            System.out.println(content.toString());
            throw e;
        }
    }

    /**
     * <desc>
     *      反向解码电梯的权限值
     * </desc>
     *
     * @param auths 电梯权限集合
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/24
     */
    public static AppElevatorAuthVO convertElevatorAuth(List<AppElevatorAuthDTO> auths){
        AppElevatorAuthVO elevator=new AppElevatorAuthVO();
        try {
            //电梯详情list
            List<AppElevatorInfoVO> results = new ArrayList<>();
            List<String> deviceId = new ArrayList<>();
            //用于去重
            Set<String> deviceIdSet = new HashSet();
            List<Map<String, Object>> setMap = new ArrayList<>();
            auths.forEach(auth -> {
                //电梯的权限机号 二进制
                String deviceAuth = StringHandlerUtil.getNullOrStringForObject(auth.getDeviceAuth());
                //待选常用居住楼层
                String floorAuth = StringHandlerUtil.getNullOrStringForObject(auth.getFloorAuth());
                //已选常用公共楼层
                String commonChoiceFloor = StringHandlerUtil.getNullOrStringForObject(auth.getCommonChoiceFloor());
                //已选常用居住楼层
                String liveChoiceFloor = StringHandlerUtil.getNullOrStringForObject(auth.getLiveChoiceFloor());
                //获取有权限的设备id 多个，号分隔
                String deviceIds = convertAuth(deviceAuth, "1");
                String deviceArray[] = splitString(deviceIds);
                int floorIndex = 0;   //获取楼层权限的下标
                //设置过期时间
                try {
                    elevator.setVailTime(DateUtil.compareSize(elevator.getVailTime(), auth.getValiTime()));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                for (String dId : deviceArray) {
                    AppElevatorInfoVO vo = new AppElevatorInfoVO();
                    if (deviceIdSet.add(dId)) {
                        //如果不是重复机号
                        elevator.setDeviceId(elevator.getDeviceId()+dId+",");
                        deviceId.add(dId);
                        vo.setDeviceId(dId);
                        //去重set
                        Set<String> floorsSet = new HashSet<>();
                        Set<String> commonsSet = new HashSet<>();
                        Set<String> liveSet = new HashSet<>();
                        if (StringUtils.isNotBlank(floorAuth)) {
                            String floors[] = splitString(floorAuth);
                            floors = splitString(convertFloor(hexToBinary(floors[floorIndex]), "1"));
                            for (String floor : floors) {
                                vo.setLiveFloor((StringUtils.isBlank(vo.getLiveFloor()) ? "" : vo.getLiveFloor()) + floor + ",");
                                floorsSet.add(floor);
                            }
                        }
                        if (StringUtils.isNotBlank(commonChoiceFloor)) {
                            String commons[] = splitString(commonChoiceFloor);
                            commonsSet.add(Integer.parseInt(commons[floorIndex], 16) + "");
                            vo.setCommonChoiceFloor((StringUtils.isBlank(vo.getCommonChoiceFloor()) ? "" : vo.getCommonChoiceFloor()) + Integer.parseInt(commons[floorIndex], 16) + ",");
                        }
                        if (StringUtils.isNotBlank(liveChoiceFloor)) {
                            String live[] = splitString(liveChoiceFloor);
                            liveSet.add(live[floorIndex] + "");
                            vo.setLiveChoiceFloor((StringUtils.isBlank(vo.getLiveChoiceFloor()) ? "" : vo.getLiveChoiceFloor()) + Integer.parseInt(live[floorIndex], 16) + ",");
                        }
                        Map<String, Object> result = new HashMap();
                        result.put("deviceId", dId);
                        result.put("floorsSet", floorsSet);
                        result.put("commonSet", commonsSet);
                        result.put("liveSet", liveSet);
                        setMap.add(result);
                        results.add(vo);
                    } else {
                        //重复机号
                        vo=results.stream().filter(result->dId.equals(result.getDeviceId())).findFirst().get();
                        for (AppElevatorInfoVO result : results) {
                            if (dId.equals(result.getDeviceId())) {
                                for (Map<String, Object> map : setMap) {
                                    if (map.get("deviceId").toString().equals(dId)) {
                                        //去重set
                                        Set<String> floorsSet = (Set) map.get("floorsSet");
                                        Set<String> commonsSet = (Set) map.get("commonsSet");
                                        Set<String> liveSet = (Set) map.get("liveSet");
                                        if (StringUtils.isNotBlank(result.getLiveFloor())) {
                                            String floors[] = splitString(floorAuth);
                                            floors = splitString(convertFloor(hexToBinary(floors[floorIndex]), "1"));
                                            for (String floor : floors) {
                                                if (floorsSet.add(floor)) {
                                                    vo.setLiveFloor(vo.getLiveFloor()+floor + ",");
                                                }
                                            }
                                        }else{
                                            String floors[] = splitString(floorAuth);
                                            floors = splitString(convertFloor(hexToBinary(floors[floorIndex]), "1"));
                                            for (String floor : floors) {
                                                if(floorsSet == null){
                                                    floorsSet = new HashSet<>();
                                                }
                                                if (floorsSet.add(floor)) {
                                                    vo.setLiveFloor((StringUtils.isBlank(vo.getLiveFloor()) ? "" : vo.getLiveFloor()) + floor + ",");
                                                }
                                            }
                                        }
                                        if (StringUtils.isNotBlank(commonChoiceFloor)) {
                                            String commons[] = splitString(commonChoiceFloor);
                                            if (commonsSet.add(Integer.parseInt(commons[floorIndex], 16) + "")) {
                                                vo.setCommonChoiceFloor(vo.getCommonChoiceFloor() + Integer.parseInt(commons[floorIndex], 16) + ",");
                                            }
                                        }
                                        if (StringUtils.isNotBlank(liveChoiceFloor)) {
                                            String live[] = splitString(liveChoiceFloor);
                                            if (liveSet.add(live[floorIndex] + "")) {
                                                vo.setLiveChoiceFloor(vo.getLiveChoiceFloor() + Integer.parseInt(live[floorIndex], 16) + ",");
                                            }
                                        }
                                        map.put("floorsSet", floorsSet);
                                        map.put("commonSet", commonsSet);
                                        map.put("liveSet", liveSet);
                                    }
                                }
                            }
                        }
                    }
                    floorIndex++;
                }
            });
            elevator.setElevatorAuth(results);
        }catch (Exception e){
            throw e;
        }
        elevator.setDeviceId(filterLastComma(elevator.getDeviceId()));
        if(elevator.getElevatorAuth()!=null && !elevator.getElevatorAuth().isEmpty()){
            for(AppElevatorInfoVO vo:elevator.getElevatorAuth()){
                if(StringUtils.isNotBlank(vo.getLiveFloor())) {
                    vo.setLiveFloor(StringUtils.join(sortStringArray(splitString(vo.getLiveFloor())), ","));
                }else {
                    vo.setLiveFloor(filterLastComma(vo.getLiveFloor()));
                }
                if(StringUtils.isNotBlank(vo.getLiveChoiceFloor())){
                    vo.setLiveChoiceFloor(StringUtils.join(sortStringArray(splitString(vo.getLiveChoiceFloor())), ","));
                }else{
                    vo.setLiveChoiceFloor(filterLastComma(vo.getLiveChoiceFloor()));
                }
                if(StringUtils.isNotBlank(vo.getCommonChoiceFloor())) {
                    vo.setCommonChoiceFloor(StringUtils.join(sortStringArray(splitString(vo.getCommonChoiceFloor())), ","));
                }else{
                    vo.setCommonChoiceFloor(filterLastComma(vo.getCommonChoiceFloor()));
                }
            }
        }
        return elevator;
    }

    /**
     * <desc>
     *      数组字符串升序排序
     * </desc>
     *
     * @param arrays
     * @return
     * @author Jiaqi.X
     * @createDate 2018/01/09
     */
    public static String[] sortStringArray(String[] arrays){
        for (int i = 0; i < arrays.length - 1; i++) {//外层循环控制排序趟数
            for (int j = 0; j < arrays.length - 1 - i; j++) {//内层循环控制每一趟排序多少次
                if (Integer.valueOf(arrays[j]) > Integer.valueOf(arrays[j + 1])) {
                    String temp = arrays[j];
                    arrays[j] = arrays[j + 1];
                    arrays[j + 1] = temp;
                }
            }
        }
        return arrays;
    }

    /**
     * <desc>
     *     根据设备类型反向解码设备的权限值
     * </desc>
     * @param deviceType  2-门禁，3-云对讲
     * @param deviceAuthList  用户的云对讲或门禁权限值与授权有效时间，MAP键值对
     * @return
     * @author cuiduawnu
     * @cerateDate 2017/11/22
     */
    public static AppEntranceOrCloudIntercomAuthVO converEntranceOrCloudIntercomAuth(Integer deviceType,List<Map<String,Object>> deviceAuthList) throws Exception{
        AppEntranceOrCloudIntercomAuthVO appEntranceOrCloudIntercomAuthVO = null;
        String[] authArr = null;
        int j = 0;  //默认为门禁
        if (PropertyEquipTypeEnum.ENTRANCE.getType()==deviceType){ //门禁
            j = PlatformConstants.MAX_ENTRANCE_DEVICEID;
        }else if (PropertyEquipTypeEnum.CLOUD_INTERCOM.getType()==deviceType){  //云对讲
            j = PlatformConstants.MAX_CLOUD_INTERCOM_DEVICEID;
        }else {
            return appEntranceOrCloudIntercomAuthVO;
        }
        int g = 0;
        String valiTimeResult =DateUtil.fomatDate(new Date());

        List<String> doorIdList = new ArrayList<>();
        if (deviceAuthList != null&&deviceAuthList.size()>0){
            appEntranceOrCloudIntercomAuthVO = new AppEntranceOrCloudIntercomAuthVO();
            g = deviceAuthList.size();
            authArr = new String[g];
            for (int i=0;i<g;i++){
                authArr[i] = deviceAuthList.get(i).get("deviceAuth").toString();
                valiTimeResult = DateUtil.compareSize(valiTimeResult,deviceAuthList.get(i).get("valiTime").toString());
            }
            appEntranceOrCloudIntercomAuthVO.setValiTime(valiTimeResult);
            for (int n=0;n<j;n++){
                boolean flag = false;
                for (int m=0;m<g;m++){
                    if(authArr[m].length()>n) {
                        if (!flag) {
                            if (!authArr[m].substring(n, n + 1).equals(PlatformConstants.ENTRANCE_NOAUTHNUM)) {
                                flag = true;
                            }
                        }
                    }
                }
                if (flag){
                    doorIdList.add(String.format("%04d",n+1));
                }
            }
            appEntranceOrCloudIntercomAuthVO.setDeviceIds(doorIdList);
        }
        return  appEntranceOrCloudIntercomAuthVO;
    }





    /**
     * <p>
     * 将为object中为null的String字符转为空字符串
     * </p>
     *
     * @param model
     * @return
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws java.lang.reflect.InvocationTargetException
     * @throws InstantiationException
     * @author Jiaqi.X
     * @createDate 2017/11/20
     */
    public static <T> Object formatString(T model) {
        Field[] field = model.getClass().getDeclaredFields();        //获取实体类的所有属性，返回Field数组
        for (int j = 0; j < field.length; j++) {     //遍历所有属性
            String name = field[j].getName();    //获取属性的名字
            //将属性的首字符大写，方便构造get，set方法
            name = name.substring(0, 1).toUpperCase() + name.substring(1);
            String type = field[j].getGenericType().toString();    //获取属性的类型
            if (type.equals("class java.lang.String")) {   //如果type是类类型，则前面包含"class "，后面跟类名
                Method m ;
                try {
                    m = model.getClass().getMethod("get" + name);
                    String value ;    //调用getter方法获取属性值
                    value = (String) m.invoke(model);
                    if (value == null) {
                        m = model.getClass().getDeclaredMethod("set" + name, String.class);
                        m.setAccessible(true);
                        m.invoke(model, "");
                    }
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        return model;
    }

    /**
     * <desc>
     *      通过sn获取项目编号
     * </desc>
     *
     * @param sn projectId+楼栋号3位+单元号2位+3位设备机号
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/22
     */
    public static String getProjectIdBySn(String sn){
        return sn.substring(0, 8);
    }

    /**
     * <desc>
     *      通过sn获取设备机号
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/22
     */
    public static String getDeviceIdBySn(String sn){
        return autlSupply(4, sn.substring(sn.length() - 4, sn.length()), "0");
    }

    /**
     * <desc>
     *      通过sn获取设备机号
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/22
     */
    public static String getDeviceIdBySnForCloudIntercom(String sn){
        return autlSupply(4, sn.substring(sn.length() - 3, sn.length()), "0");
    }

    /**
     * <desc>
     *      通过sn获取云对讲设备唯一码
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/22
     */
    public static String getDeviceUniqueBySn(String sn){
        return getProjectIdBySn(sn) + "3" + getDeviceIdBySnForCloudIntercom(sn);
    }

    /**
     * <desc>
     *      根据deviceUnique获取sn
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2019/04/28
     */
    public static String getSnByDeviceUnique(String deviceUnique){
        return getProjectIdByDeviceUnique(deviceUnique) + "0000" + getDeviceIdByDeviceUnique(deviceUnique);
    }

    /**
     * <desc>
     *      通过sn获取云电梯设备唯一码
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/22
     */
    public static String getElevatorDeviceUniqueBySn(String sn){
        return getProjectIdBySn(sn) + "1" + getDeviceIdBySn(sn);
    }

    /**
     * <desc>
     *      通过sn获取门禁设备唯一码
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/22
     */
    public static String getEntranceDeviceUniqueBySn(String sn){
        return getProjectIdBySn(sn) + "2" + getDeviceIdBySn(sn);
    }

    /**
     * <desc>
     *      通过sn获取云群控器设备唯一码
     * </desc>
     *
     * @param sn
     * @return
     * @author Qiang.S
     * @createDate 2019/04/26
     */
    public static String getControllerDeviceUniqueBySn(String sn){
        return getProjectIdBySn(sn) + "5" + getDeviceIdBySn(sn);

    }
    /**
     * <desc>
     *      通过sn获取楼栋号
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/22
     */
    public static String getBuildNumBySn(String sn){
        return sn.substring(sn.length()-8,sn.length()-5);
    }

    /**
     * <desc>
     *      通过sn获取单元号
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/22
     */
    public static String getUnitBySn(String sn){
        return sn.substring(sn.length()-5,sn.length()-3);
    }


    /**
     * <desc>
     *      过滤字符串末尾的,号
     * </desc>
     *
     * @param str
     * @return
     * @author Jiaqi.X
     * @createDate 2017/11/23
     */
    public static String filterLastComma(String str){
        if(StringUtils.isNotBlank(str) && str.substring(str.length()-1,str.length()).equals(",")){
            str=str.substring(0,str.length()-1);
        }
        return str;
    }


    /**
     * <desc>
     *    把16进制字符串转换成字节数组.
     * </desc>
     *
     * @param hex 待转换的Hex字符串
     * @return 转换得到的byte数组
     * @author LewisLouis
     * @createDate 2017-11-10
     */
    public static byte[] hexStrToBytes(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }
        return result;
    }

    /**
     * <desc>
     *    将单个十六进制字符转换为字节
     * </desc>
     *
     * @param c 单个字符
     * @return 转换得到的byte
     * @author LewisLouis
     * @createDate 2017-11-10
     */
    private static byte toByte(char c) {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }


    /**
     * <desc>
     *    把字节数组转换成16进制字符串.
     * </desc>
     *
     * @param bArray 待转换的byte数组
     * @return 转换得到的Hex字符串
     * @author LewisLouis
     * @createDate 2017-11-10
     */
    public static String bytesToHexStr(byte[] bArray) {
        if(bArray == null )
        {
            return "";
        }
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * <desc>
     *    自动后补齐字符串
     * </desc>
     *
     * @param str    字符串
     * @param supply 待填充的字符
     * @param length 要求填充后达到的字符串总长度
     * @return 填充后的字符串
     * @author LewisLouis
     * @createDate 2017-11-10
     */
    public static String fillString(String str, String supply,int length) {
        StringBuffer sb = new StringBuffer(str);
        while (sb.length() < length) {
            sb.append(supply);
        }
        return sb.toString();
    }


    /**
     * <desc>
     *    查找字符串是否包含特殊字符，如有返回true，否则 false
     * </desc>
     *
     * @param source    要查找的字符
     * @return
     * @author Wenchao.L
     * @createDate 2017-12-14
     */
    public static boolean findSpecialWords(String source) {
        Matcher m = Pattern.compile(PlatformConstants.regEx).matcher(source);
        while (m.find()) {
            return true;
        }
        return false;
    }

    /**
     * <desc>
     *      过滤特殊字符串
     * </desc>
     *
     * @param str
     * @return
     * @author Jiaqi.X
     * @createDate 2019/05/23
     */
    public static String filterSpecialStr(String str){
        String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }


    /**
     * <desc>
     *      检测是否有emoji字符
     * </desc>
     *
     * @param source 需要判断的字符串
     * @return 一旦含有就抛出
     * @author Jiaqi.X
     * @createDate 2019/05/23
     */
    public static boolean containsEmoji(String source) {
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (!notisEmojiCharacter(codePoint)) {
                //判断确认有表情字符
                return true;
            }
        }
        return false;
    }



    /**
     * <desc>
     *      非emoji表情字符判断
     * </desc>
     *
     * @param codePoint
     * @return
     * @author Jiaqi.X
     * @createDate 2019/05/23
     */
    private static boolean notisEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) ||
                (codePoint == 0x9) ||
                (codePoint == 0xA) ||
                (codePoint == 0xD) ||
                ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
                ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
                ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    /**
     * <desc>
     *      过滤emoji 或者 其他非文字类型的字符
     * </desc>
     *
     * @param source  需要过滤的字符串
     * @return
     * @author Jiaqi.X
     * @createDate 2019/05/23
     */
    public static String filterEmoji(String source) {
        if (!containsEmoji(source)) {
            return source;//如果不包含，直接返回
        }

        StringBuilder buf = null;//该buf保存非emoji的字符
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (notisEmojiCharacter(codePoint)) {
                if (buf == null) {
                    buf = new StringBuilder(source.length());
                }
                buf.append(codePoint);
            }
        }

        if (buf == null) {
            return "";//如果没有找到非emoji的字符，则返回无内容的字符串
        } else {
            if (buf.length() == len) {
                buf = null;
                return source;
            } else {
                return buf.toString();
            }
        }
    }


    /**
     * <desc>
     *    过滤关键字
     * </desc>
     *
     * @param resource   需过滤的字符
     * @return  过滤后结果
     * @author Wenchao.L
     * @createDate 2017-12-14
     */
    public static String filterSpecialWords(String resource){
        Pattern p = Pattern.compile(PlatformConstants.regEx);
        Matcher m = p.matcher(resource);
        return m.replaceAll("").trim();
    }

    /**
     * <desc>
     *      取语言类型。
     * <desc/>
     *
     * @param  lanType 语种
     * @return codes 第一个是中文 第二个是其他语种，限制亮个
     * @author shengen.T
     * @createDate 2017-12-29
     */
    public static ErrorCode getErrCode(String lanType, Object... codes){
        if(StringUtils.isBlank(lanType)){
            return BaseErrorCodeEnum.NOT_PARAM.getErrorCode();
        }
        if (StringHandlerUtil.compareStrIgnoreCaseWithOutEmpty(lanType, LanguageTypeEnum.CHINESE.getDescription())){
            if (codes.length > 0){
                return ((AppErrorCodeEnum)(codes[0])).getErrorCode();
            }
        } else {
            if (codes.length > 1){
                return ((AppErrorCodeEnum)(codes[1])).getErrorCode();
            }
        }
        return null;
    }

    /**
     * <desc>
     *      呼梯楼层范围检验。
     * <desc/>
     *
     * @param  fromFloor 出发楼层
     * @param  toFloor 目标楼层
     * @param  maxFloor
     * @return
     * @author shengen.T
     * @createDate 2018-03-30
     */
    public static <T> Map checkFloor(String fromFloor,String toFloor,Integer maxFloor){
        Map resultMap = new HashMap<>();
        Integer toNum  = StringHandlerUtil.strToIntDef(toFloor,10000);
        Integer fromNum = StringHandlerUtil.strToIntDef(fromFloor,10000);
        Integer toNumTmp = toNum>0?toNum:(toNum*-1);
        Integer fromNumTmp = fromNum>0?fromNum:(fromNum*-1);
        if((fromNum>maxFloor) || (fromNum<(-1*(maxFloor-1))) || (fromNum==0)){
            resultMap.put("code",1);
            resultMap.put("message","出发楼层不合法！");
        }else if((toNum>maxFloor) || (toNum<(-1*(maxFloor-1))) || (toNum==0)){
            resultMap.put("code",2);
            resultMap.put("message","目标楼层不合法！");
        }else if(toNum==fromNum){
            resultMap.put("code",3);
            resultMap.put("message","出发楼层和目标楼层不能一样！");
        }else if((toNumTmp+fromNumTmp)>(maxFloor*2)){
            resultMap.put("code",4);
            resultMap.put("message","楼层超出范围！");
        }else {
            resultMap.put("code",0);
            resultMap.put("message","");
        }
        return resultMap;
    }

    /**
     * <desc>
     *      通过楼层标识生成电梯权限
     * <desc/>
     *
     * @param floorSigns 楼层标识1,3,5
     * @param mark 1表示正数 2表示负数
     * @return
     * @author zhangs
     * @createDate 2017/10/10
     */
    public static String getCloudElevatorInFloor(String floorSigns,Integer mark) {
        Integer num;
        StringBuilder sb = new StringBuilder();
        if(mark == 1){
            num = 128;
        }else{
            num = 8;
        }
        for(int i = 0 ; i < num ;i++){
            sb.append("0");
        }
        String floors[] = StringHandlerUtil.splitString(floorSigns);
        for(String floor : floors){
            int f = Integer.valueOf(floor);
            if(f <= num) {
                sb.replace(f - 1, f, "1");
            }
        }
        if(mark.equals(2)){
            sb.reverse();
        }
        return binaryToHex(sb.toString()).toUpperCase();
    }

    /**
     * <desc>
     *      通过楼层标识生成电梯权限
     * <desc/>
     *
     * @param floorSigns 楼层标识1,3,5
     * @param mark 1表示正数 2表示负数
     * @return
     * @author zhangs
     * @createDate 2017/10/10
     */
    public static String getCloudElevatorInFloorBinary(String floorSigns,Integer mark) {
        Integer num;
        StringBuilder sb = new StringBuilder();
        if(mark == 1){
            num = 128;
        }else{
            num = 8;
        }
        for(int i = 0 ; i < num ;i++){
            sb.append("0");
        }
        String floors[] = StringHandlerUtil.splitString(floorSigns);
        for(String floor : floors){
            int f = Integer.valueOf(floor);
            if(f <= num) {
                sb.replace(f - 1, f, "1");
            }
        }
        if(mark.equals(2)){
            sb.reverse();
        }
        return sb.toString();
    }

    /**
     * <desc>
     *      通过楼层标识生成电梯权限
     * <desc/>
     *
     * @param floorSigns 楼层标识1,3,5
     * @return
     * @author Jiaqi.X
     * @createDate 2018/05/24
     */
    public static String getQrCodeSDKFloor(String floorSigns) {
        Integer num = 112;
        StringBuilder sb = new StringBuilder();
        for(int i = 0 ; i < num ;i++){
            sb.append("0");
        }
        String floors[] = StringHandlerUtil.splitString(floorSigns);
        for(String floor : floors){
            int f = Integer.valueOf(floor);
            if(f <= num) {
                sb.replace(f - 1, f, "1");
            }
        }
        return binaryToHex(sb.toString()).toUpperCase();
    }

    /**
     * <desc>
     *      将图片字符串转为字节数组
     * </desc>
     *
     * @param imgStr
     * @return
     * @author Jiaqi.X
     * @createDate 2018/05/21
     */
    public static byte[] imageBase64StrToByte(String imgStr) {   //对字节数组字符串进行Base64解码并生成图片
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            //Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for(int i=0;i<b.length;++i) {
                if(b[i]<0) {//调整异常数据
                    b[i]+=256;
                }
            }
            return b;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * <desc>
     *      将16进制转换成byte
     * </desc>
     *
     * @param str
     * @return
     * @author Qiang.S
     * @createDate 2018/09/13
     */
    public static byte[] hexStringToByteArray(String str) {
        int len = str.length();
        byte[] data = new byte[len / 2];
        try {
            for (int i = 0; i < len; i += 2) {
                data[i / 2] = (byte) ((Character.digit(str.charAt(i), 16) << 4)
                        + Character.digit(str.charAt(i+1), 16));
            }
        } catch (Exception e) {
            return null;
        }
        return data;
    }

    /**
     * <desc>
     *      将字符转换成16进制并补位
     * </desc>
     *
     * @param content
     * @param num
     * @return
     * @author Qiang.S
     * @createDate 2018/09/13
     */
    public static String intToHexString(int content, int num) {
        String str = Integer.toHexString(content);
        int makeup = num * 2 - str.length();
        StringBuilder sb = new StringBuilder();
        while (makeup > 0) {
            sb.append("0");
            makeup--;
        }
        sb.append(str);

        return sb.toString();
    }

    /**
     * <desc>
     *      将byte转换成16进制
     * </desc>
     *
     * @param src
     * @return
     * @author Qiang.S
     * @createDate 2018/09/13
     */
    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * <desc>
     *      根据门数获取sn集合
     * </desc>
     *
     * @param sn
     * @param doorCount 门数
     * @return
     * @author Juguang.S
     * @createDate 2019/02/21
     */
    public static List<String> getSnByDoorNum(String sn,int doorCount){
        int deveid = Integer.parseInt(sn.substring(13,sn.length()))-1;
        List<String> snList = new ArrayList<>();
        for( int j=0;j<doorCount;j++){
            deveid++;
            if(deveid>=1000){
                snList.add(String.format("%s%03d", sn.substring(0,12), deveid));
            }else{
                snList.add(String.format("%s%03d", sn.substring(0,13), deveid));
            }
        }
        return snList;
    }

    /**
     * <desc>
     *      判断字符串中数字是否一致
     * </desc>
     *
     * @param str
     * @return
     * @author Juguang.S
     * @createDate 2019/02/22
     */
    public static boolean isSameChars(String str) throws IllegalArgumentException {
        char first = str.charAt(0);
        for (int i=1; i<str.length(); i++){
            if ((str.charAt(i) != first)){
                return true;
            }
        }
        return false;
    }

    /**
     * <desc>
     *      判断字符串中四位数字是否是递增或递减
     * </desc>
     *
     * @param str
     * @return
     * @author Juguang.S
     * @createDate 2019/02/22
     */
    public static boolean isContinuousNumber(String str){
        int a = Integer.parseInt(str.substring(0,1));
        int b = Integer.parseInt(str.substring(1,2));
        int c = Integer.parseInt(str.substring(2,3));
        int d = Integer.parseInt(str.substring(3,4));
        if(((a+1==b) && (b+1==c) && (c+1==d)) || ((a-1==b) && (b-1==c) && (c-1==d))){
            return false;
        }
        return true;
    }

    /**
     * <desc>
     *      去重逗号分隔的字符串
     * </desc>
     *
     * @param text
     * @return
     * @author Qiang.S
     * @createDate 2020/01/10
     */
    public static String duplicateEemoval(String text){
        String[] str = text.split(",");
        if(str.length == 0) {
            return null;
        }
        List<String> list = new ArrayList<String>();
        StringBuffer sb = new StringBuffer();
        for(int i = 0;i < str.length; i++) {
            if(!list.contains(str[i])){
                list.add(str[i]);
                sb.append(str[i]+",");
            }
        }
        return sb.toString().substring(0,sb.toString().length()-1);
    }


    /**
     * <desc>
     *     判断对象的所有属性是否为空
     * </desc>
     *
     * @Author chengshican
     * @Date 2020-11-25 10:41
     * @Param
     * @Return
     * @Exception
     */
    public static boolean allFieldIsNotNull(Object o) {
        try {
            for (Field field : o.getClass().getDeclaredFields()) {
                //把私有属性公有化
                field.setAccessible(true);
                Object object = field.get(o);
                if (Objects.isNull(object)) {
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * <desc>
     *      逗号隔开字符串逆序
     * </desc>
     *
     * @author pengwei
     * @createDate 2020/12/02
     */
    public  static  String  getReverseStr(String  floor){
        if(StringUtils.isEmpty(floor)){
            return "";
        }
        String[]  floorArr  =  floor.split(",");
        StringJoiner  floorJoin  = new StringJoiner(",");
        for(int i=floorArr.length-1;i>=0;i--){
            floorJoin.add(floorArr[i]);
        }
        return  floorJoin.toString();
    }

    /**
     * <desc>
     *      将二进制电梯权限和16进制楼层权限转换Map<deviceUnique, floorAuth>
     * </desc>
     *
     * @param elevatorAuthMap 电梯和楼层权限
     * @param projectId 项目id
     * @return
     * @Author Zhu.yj
     * @createDate  2021/3/31
     */
    public static Map<String, String> assembleElevatorAuth(Map<String, Object> elevatorAuthMap, String projectId){
        if(elevatorAuthMap == null){
            return null;
        }
        String deviceAuth = elevatorAuthMap.get("deviceAuth").toString();
        String floorAuth = elevatorAuthMap.get("floorAuth").toString();

        //解析设备权限
        List<String> deviceIdList = StringHandlerUtil.splitStringList(StringHandlerUtil.convertAuth(deviceAuth, "1"));
        //拼接deviceUnique
        List<String> floorAuthList = StringHandlerUtil.splitStringList(floorAuth);
        Map<String, String> elevatorFloorAuthMap = new HashMap<>();
        for (int i = 0; i< deviceIdList.size(); i++){
            String currentFloorAuth = floorAuthList.get(i);
            String  naturalFloorNum   =  StringHandlerUtil.convertFloor(StringHandlerUtil.hexToBinary(currentFloorAuth),"1");
            elevatorFloorAuthMap.put(projectId + PropertyEquipTypeEnum.ELEVATOR.getType() + deviceIdList.get(i), naturalFloorNum);
        }
        return elevatorFloorAuthMap;
    }

    /**
     * <desc>
     *      组装二维码字符串
     * </desc>
     *
     * @param entrances 门禁设备机号，多个逗号隔开
     * @param elevators 电梯设备机号
     * @param projectId 项目id
     * @param startTime 访客二维码有效开始时间
     * @param validTime 有效时间
     * @param batchNumber 流水号hex码 刷新同一个二维码时此字段变更
     * @param projectKey  项目秘钥
     * @param validCounts 可用次数
     * @param identifier 电梯门禁权限 01只有电梯权限 02只有门禁权限 03有电梯和门禁权限
     * @param uid 二维码中区分用户唯一标识，同一项目下的不同访客应该有不同的uid
     * @return  二维码字符串
     * @Author Zhu.yj
     * @createDate  2021/6/1
     */
    public static String createQrCodeContent(String entrances, String elevators, String projectId, String startTime, Integer validTime, String batchNumber, String projectKey, Integer validCounts, String identifier, String uid) throws ParseException, NoSuchProviderException {

        /*
            拼装二维码 开头ITL{L:包长度 ,V:版本，U:用户id 8位16进制数 同一项目不同用户id具有唯一性，
            M:用户类型 H:房屋编号 I:流水号，T:启用时间,P:有效时间段，G{}门禁权限，K:mac码
         */
        //二维码开头
        String head = "ITL:{L:";
        StringBuilder content = new StringBuilder();
        //组装版本
        content.append("V:").append(AppQrcodeProtocolVersionEnum.NEW.getType()).append(",");
        //组装uid
        content.append("U:").append(uid).append(",");
        //组装用户类型为访客
        content.append("M:").append(AppQrcodeUserTypeEnum.VISITOR.getType()).append(",");
        //设置流水号
        content.append("I:").append(StringHandlerUtil.autlSupply(4, batchNumber, "0")).append(",");

        //设置启用时间
        Calendar beforeTime = Calendar.getInstance();
        beforeTime.setTime(DateUtil.formatStringToDate(startTime, DateUtil.YYMMDDHHMM));
        beforeTime.add(Calendar.MINUTE, -10);// 10分钟之前的时间
        Date beforeD = beforeTime.getTime();
        startTime = DateUtil.fomatDate(beforeD, DateUtil.YYMMDDHHMM);
        content.append("T:").append(startTime).append(",");
        //设置有效时间段
        content.append("P:").append(StringHandlerUtil.autlSupply(4, Integer.toHexString(validTime), "0").toUpperCase()).append(",");

        String validCount;
        if (validCounts != null && validCounts != 0) {
            //有效次数 hex码
            content.append("S:").append(StringHandlerUtil.autlSupply(4,
                    Integer.toHexString(validCounts), "0").toUpperCase()).append(",");
            validCount = StringHandlerUtil.autlSupply(4, Integer.toHexString(validCounts), "0").toUpperCase();
        } else {
            //有效次数 hex码
            content.append("S:0000,");
            validCount = "00";

        }
        if (validCount.length() > 2) {
            validCount = validCount.substring(2, 4);
        }

        //组装生成key的init_value
        String value = startTime + StringHandlerUtil.autlSupply(4, Integer.toHexString(validTime), "0").toUpperCase() + validCount;
        //设置设备权限
        if (identifier == null){
            identifier = "00";
        }
        if (!identifier.equals("00")) {
            //门禁
            if (!identifier.equals("01")) {
                //设置二维码的门禁数量
                String[] entranceDeviceUniques = StringHandlerUtil.splitString(entrances);
                content.append("G:{");
                if (entranceDeviceUniques.length > 0 && entranceDeviceUniques.length < 255) {
                    //设置二维码的门禁权限 HEX码
                    String n1 = StringHandlerUtil.assembleQrcodeDeviceNum(entranceDeviceUniques);
                    String n2 = StringHandlerUtil.assembleNewDeviceNum(entranceDeviceUniques);
                    if (n1.length() > n2.length()) {
                        content.append("N2:" + n2);
                    } else {
                        content.append("N1:" + n1);
                    }
                } else {
                    content.append("N3:0");
                }
                content.append("},");
            }
            //电梯
            if (!identifier.equals("02")) {
                //设置二维码的电梯权限
                List<SmartCardQRCodeElevatorAuthDTO> elevatorAuthDTOS = JSON.parseArray(elevators, SmartCardQRCodeElevatorAuthDTO.class);
                for (SmartCardQRCodeElevatorAuthDTO elevator : elevatorAuthDTOS) {

                    content.append("Q:{");
                    //设置机号权限N1：xxx
                    String n1 = StringHandlerUtil.assembleQrcodeDeviceNum(StringHandlerUtil.splitString(elevator.getDeviceId()));
                    String n2 = StringHandlerUtil.assembleNewDeviceNum(StringHandlerUtil.splitString(elevator.getDeviceId()));
                    if (n1.length() > n2.length()) {
                        content.append("N2:").append(n2).append(",");
                    } else {
                        content.append("N1:").append(n1).append(",");
                    }
                    //设置有权限的楼层数量 HEX码
                    String fl = elevator.getFloors();
                    String[] floorNo = StringHandlerUtil.splitString(fl);
                    // String chCommonFloor = fl.substring(fl.indexOf("c") + 1, fl.length());
                    if (floorNo.length == 112) {
                        content.append("X3:0,");
                    } else {
                        n1 = StringHandlerUtil.assembleQrcodeDeviceNum(floorNo);
                        n2 = StringHandlerUtil.assembleNewDeviceNum(floorNo);
                        if (n1.length() > n2.length()) {
                            content.append("X2:").append(n2).append(",");
                        } else {
                            content.append("X1:").append(n1).append(",");
                        }
                    }
                    //设置直达楼层
                    String noStopFloors = elevator.getNoStopFloors();
                    if (StringUtils.isNotBlank(noStopFloors) &&
                            noStopFloors.length() > 0) {
                        content.append("Y:").append(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(noStopFloors)).toUpperCase(), "0"));
                    } else {

                        content.append("Y:00");
                    }
                    content.append("},");
                }
            }
        }


        String mac = "K:" + DesEncryptUtil.newOwnerAndVisitorMacEncrypt(value, projectKey, content.toString());
        String qrcode = head + StringHandlerUtil.autlSupply(4, Integer.toHexString((content + mac).length()).toUpperCase(), "0") + "," + content + mac + "}";
        return qrcode;
    }
}
